package top.yudoge.dogeeditor.app.web

import lombok.extern.slf4j.Slf4j
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import top.yudoge.dogeeditor.app.query.CreateChatSessionQuery
import top.yudoge.dogeeditor.app.query.RenewChatSessionQuery
import top.yudoge.dogeeditor.app.query.RevokeChatSessionQuery
import top.yudoge.dogeeditor.commons.web.Response
import top.yudoge.dogeeditor.llm.memory.SessionMemory
import java.util.UUID

/**
 * Web interface about chat session.
 */
@RestController
@RequestMapping("/chat-session")
class ChatSessionController {

    @Autowired
    private lateinit var sessionMemory: SessionMemory

    /**
     * Create a chat session.
     * When the session is created, a session-private store like Map<String, String> will be created for this session.
     * User can use this store to save the shared data between multiple chat requests or app and llm module.
     *
     * Session has a limited alive time. When the session is expired, the store will be removed.
     * User(like web application) can renew the session to extend the alive time.
     *
     * The store we created will be distributed to make sure it can be shared with multiple server instances or modules.
     * (But now we use a simple InMemoryCache)
     */
    @PostMapping("/create")
    fun createChatSession(@RequestBody query: CreateChatSessionQuery): Response<String> {
        // todo limit the maximum number of sessions that one ip address can create
        //      (and total number of all ip addresses).
        val sessionId = UUID.randomUUID().toString()
        sessionMemory.newSession(sessionId, query.expireTime)
        println("create session: $sessionId -> ${query.expireTime}")
        return Response.success(sessionId)
    }


    /**
     * Revoke a session
     */
    @PostMapping("/revoke")
    fun revokeChatSession(@RequestBody query: RevokeChatSessionQuery): Response<Boolean> {
        println("revoke session: ${query.sessionId}")
        return Response.success(sessionMemory.revoke(query.sessionId))
    }

    /**
     * Renew a session
     *
     * Session has a limited alive time. When the session is expired, the store will be removed.
     * User(like web application) can use this interface to extend the alive time of a session.
     */
    @PostMapping("/renew")
    fun renewChatSession(@RequestBody query: RenewChatSessionQuery): Response<Boolean> {
        println("renew session: ${query.sessionId} -> ${query.expireTime}")
        return Response.success(true)
    }

}